package com.zyb.lmbackend.controller;

/**
 * 类目归纳相关控制器。
 *
 * 提供：
 * - 触发基于样本的类目归纳（返回插入数量与预览候选）
 * - 批量批准类目（将预览项落库为启用状态）
 */
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zyb.lmbackend.dto.BuildResponseDto;
import com.zyb.lmbackend.dto.CategoryDictDto;
import com.zyb.lmbackend.entity.CategoryDict;
import com.zyb.lmbackend.llm.model.CategoryDef;
import com.zyb.lmbackend.service.CategoryDictService;
import com.zyb.lmbackend.service.TaxonomyBuilderService;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Validated
@RequestMapping("/api/taxonomy")
@RequiredArgsConstructor
public class TaxonomyController {

    private final TaxonomyBuilderService taxonomyBuilderService;
    private final CategoryDictService categoryDictService;
    private final ObjectMapper objectMapper;

    @Operation(summary = "抽样原始退货数据给第一个大模型完成归纳")
    @PostMapping("/build")
    /**
     * 基于数据库随机抽样的退货原因，调用大模型进行类目归纳。
     *这个接口是让大模型打分超过0.7分，并且没有被分类为other的退货类型直接入库，不满足这两个会把大模型分析不出来的数据返回前端让用户二次分类
     * @param sampleSize 样本条数（可选）
     * @return 插入数量 + 预览候选（不直接入库）
     */
    public ResponseEntity<BuildResponseDto> build(@RequestParam(required = false) Integer sampleSize) {
        var res = taxonomyBuilderService.build(sampleSize);
        List<CategoryDictDto> preview = res.preview.stream().map(this::toDto).collect(Collectors.toList());
        BuildResponseDto body = new BuildResponseDto(res.inserted, preview);
        return ResponseEntity.ok(body);
    }

    @Operation(summary = "Approve taxonomy categories")
    @PostMapping("/approve")
    /**
     * 批量批准类目：存在则更新，不存在则新增，统一置为启用(is_active=1)。
     */
    public ResponseEntity<Void> approve(@RequestBody List<CategoryDictDto> items) {
        if (items == null || items.isEmpty()) return ResponseEntity.ok().build();
        for (CategoryDictDto d : items) {
            if (d.getCode() == null || d.getName() == null) continue;
            String code = d.getCode().trim().toUpperCase(Locale.ROOT);
            CategoryDict exist = categoryDictService.getOne(new LambdaQueryWrapper<CategoryDict>().eq(CategoryDict::getCode, code));
            String keywordsJson = "[]";
            try {
                keywordsJson = objectMapper.writeValueAsString(d.getKeywords());
            } catch (JsonProcessingException ignored) {
            }
            if (exist == null) {
                // 新增
                CategoryDict e = new CategoryDict();
                e.setCode(code);
                e.setName(d.getName());
                e.setDefinition(d.getDefinition());
                e.setKeywords(keywordsJson);
                e.setIsActive((byte) 1);
                categoryDictService.save(e);
            } else {
                // 更新
                exist.setName(d.getName());
                exist.setDefinition(d.getDefinition());
                exist.setKeywords(keywordsJson);
                exist.setIsActive((byte) 1);
                categoryDictService.updateById(exist);
            }
        }
        return ResponseEntity.ok().build();
    }

    private CategoryDictDto toDto(CategoryDef def) {
        CategoryDictDto dto = new CategoryDictDto();
        dto.setCode(def.getCode());
        dto.setName(def.getName());
        dto.setDefinition(def.getDefinition());
        dto.setKeywords(def.getKeywords());
        dto.setIsActive(1);
        return dto;
    }
}
